#= require "moz_websocket"
#= require "vendor/jquery.json-2.2"
#= require "vendor/swfobject"
#= require "vendor/web_socket"
//= provide "../swf"

window.WEB_SOCKET_SWF_LOCATION = "<%= asset_path 'WebSocketMain.swf' %>"

class @AlondraClient
  constructor: (@server, @channels=[], @token = null, @retry = 10000) ->

    @channels = [@channels] unless @channels instanceof Array

    @url = "ws://#{@server}"
    @url += "?token=#{@token}" if @token

    @connect()

  subscribe: (channel) =>
    @channels.push(channel)

    if @socket.readyState ==  0
      # Socket is connecting
      # Schedule for later subscription

      return

    subscription =
      command: 'subscribe'
      channel: channel

    @socket.send $.toJSON(subscription)
    @

  unsubscribe: (channel) =>
    channelIndex = @channels.indexOf(channel)
    @channels.splice(channelIndex, 1) if channelIndex >= 0

    if @socket.readyState == 1
      unsubscription =
        command: 'unsubscribe'
        channel: channel

      @socket.send $.toJSON(unsubscription)

    return this

  opened: () =>
    if @reconnectInterval
      clearInterval(@reconnectInterval)
      @reconnectInterval = null

    @subscribe(channel) for channel in @channels
    $(this).trigger('connected')
    true

  connect: =>
    @socket = new WebSocket(@url)

    @socket.onopen = @opened

    @socket.onclose = () =>
      this.reconnect()
      $(this).trigger('disconnected')

    @socket.onmessage = (message) =>
      msg = $.parseJSON(message.data)
      if msg.event
        @process(msg)
      else
        @execute(msg)


    @socket.onerror = (error) =>
      @reconnect()
      $(this).trigger('error', error)

    @

  process: (serverEvent) ->
    eventName    = serverEvent.event
    resourceType = serverEvent.resource_type
    resource     = serverEvent.resource

    $(@).trigger("#{eventName}.#{resourceType}", resource)

  execute: (message) ->
    eval(message.message)

  reconnect: ->
    return if !@retry || @reconnectInterval

    @reconnectInterval = setInterval =>
      this.connect()
    ,@retry

